home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
comm2
/
parnet.lha
/
parnet
/
sources
/
unit_dgr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-09
|
4KB
|
198 lines
/*
* UNIT_DGR.C DATAGRAM PROTOCOL
*/
#include "defs.h"
void DGramBeginIO(Iob *);
void DGramAbortIO(Iob *);
void DGramClose(Iob *);
void DGramData(int, Packet *, long);
void UnitDGramOpen(Iob *, long, long);
/*
* Called under Forbid
*/
void
UnitDGramOpen(iob, unitnum, flags)
Iob *iob;
long unitnum;
long flags;
{
Unit *unit;
if (unit = FindUnitForPort(iob->io_Port)) {
if (unit->BeginIO != DGramBeginIO) {
iob->io_Error = PPERR_PORT_IN_USE;
return;
}
} else {
unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
}
iob->io_Unit = unit;
++unit->RefCnt;
}
void
DGramClose(iob)
Iob *iob;
{
Unit *unit = iob->io_Unit;
if (--unit->RefCnt == 0) {
FreeUnit(unit);
}
iob->io_Unit = NULL;
}
/*
* UnitDGramData() is called whenever a low level network operation
* completes for the given unit. cmd is:
*
* 'r' received data packet
* 'w' wrote data packet
* 'W' timeout writing data packet
*
* The routine is called with the unix locked.
*
* WARNING: This call may not requeue synchronous packets, a lockout
* will result.
*/
void
DGramData(cmd, packet, actual)
int cmd;
Packet *packet;
long actual; /* 'w', 'W' */
{
Unit *unit = packet->io_Unit;
Iob *iob = packet->iob; /* NULL for 'r' */
long n;
switch(cmd) {
case 'r':
#ifdef DEBUG
sprintf(StickyPort->DebugBuf, " RDDRG %d",actual);
#endif
if (iob = (Iob *)RemHead(&unit->PendIOR)) {
iob->io_Flags &= ~IOF_QUEUED;
n = actual;
if (n < 0)
n = 0;
if (n > iob->io_Length) {
n = iob->io_Length;
iob->io_Error = PPERR_WARN_OVFLOW;
}
actual -= n;
movmem((char *)packet->Data1, (char *)iob->io_Data, n);
if (iob->io_Length2 && actual > 0) { /* a second data buffer */
if (actual > iob->io_Length2)
actual = iob->io_Length2;
movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
n += actual;
}
iob->io_Actual = n;
if ((iob->io_Flags & IOF_QUICK) == 0)
ReplyMsg(&iob->io_Message);
}
/*
* Note that if no read requests are pending the datagram is
* thrown away.
*/
FreeParPacket(packet);
break;
case 'W':
#ifdef DEBUG
sprintf(StickyPort->DebugBuf, " TMDRG %d",actual);
#endif
Remove(iob);
iob->io_Flags &= ~IOF_QUEUED;
iob->io_Error = 1;
iob->io_Actual = actual;
if ((iob->io_Flags & IOF_QUICK) == 0)
ReplyMsg(&iob->io_Message);
FreeParPacket(packet);
break;
case 'w':
#ifdef DEBUG
sprintf(StickyPort->DebugBuf, " WRDRG %d",actual);
#endif
Remove(iob);
iob->io_Flags &= ~IOF_QUEUED;
iob->io_Actual = actual;
if ((iob->io_Flags & IOF_QUICK) == 0)
ReplyMsg(&iob->io_Message);
FreeParPacket(packet);
break;
}
}
void
DGramBeginIO(iob)
Iob *iob;
{
Unit *unit = iob->io_Unit;
Packet *packet;
iob->io_Error = 0;
iob->io_Actual = 0;
iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
switch(iob->io_Command) {
case CMD_READ:
LockAddr(unit->UnitLock);
iob->io_Flags &= ~IOF_QUICK;
iob->io_Flags |= IOF_QUEUED;
AddTail(&unit->PendIOR, iob);
UnlockAddr(unit->UnitLock);
return;
case CMD_WRITE:
packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
LockAddr(unit->UnitLock);
AddTail(&unit->PendIOW, iob);
UnlockAddr(unit->UnitLock);
QueuePacketForWrite(packet);
return;
default:
CtlBeginIO(iob);
return;
}
}
/*
* Abort a read or write request. Currently only read requests may be
* aborted.
*/
void
DGramAbortIO(iob)
Iob *iob;
{
if (iob->io_Command == CMD_READ) {
LockAddr(iob->io_Unit->UnitLock);
if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
Remove(iob);
UnlockAddr(iob->io_Unit->UnitLock);
iob->io_Flags &= ~IOF_QUEUED;
iob->io_Error = -1; /* ??? */
ReplyMsg(&iob->io_Message);
} else {
UnlockAddr(iob->io_Unit->UnitLock);
}
}
}